home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / stdlib / RCS / strtoul.c,v < prev    next >
Encoding:
Text File  |  1991-11-24  |  5.1 KB  |  258 lines

  1. head     1.2;
  2. branch   ;
  3. access   ;
  4. symbols  sprited:1.2.1;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.2
  10. date     89.03.22.00.47.33;  author rab;  state Exp;
  11. branches 1.2.1.1;
  12. next     1.1;
  13.  
  14. 1.1
  15. date     88.06.17.18.00.17;  author ouster;  state Exp;
  16. branches ;
  17. next     ;
  18.  
  19. 1.2.1.1
  20. date     91.11.23.23.10.27;  author kupfer;  state Exp;
  21. branches ;
  22. next     ;
  23.  
  24.  
  25. desc
  26. @@
  27.  
  28.  
  29. 1.2
  30. log
  31. @*** empty log message ***
  32. @
  33. text
  34. @/* 
  35.  * strtoul.c --
  36.  *
  37.  *    Source code for the "strtoul" library procedure.
  38.  *
  39.  * Copyright 1988 Regents of the University of California
  40.  * Permission to use, copy, modify, and distribute this
  41.  * software and its documentation for any purpose and without
  42.  * fee is hereby granted, provided that the above copyright
  43.  * notice appear in all copies.  The University of California
  44.  * makes no representations about the suitability of this
  45.  * software for any purpose.  It is provided "as is" without
  46.  * express or implied warranty.
  47.  */
  48.  
  49. #ifndef lint
  50. static char rcsid[] = "$Header: /sprite/src/lib/c/stdlib/RCS/strtoul.c,v 1.1 88/06/17 18:00:17 ouster Exp Locker: rab $ SPRITE (Berkeley)";
  51. #endif /* not lint */
  52.  
  53. #include <sprite.h>
  54. #include <stdlib.h>
  55. #include <ctype.h>
  56.  
  57. /*
  58.  * The table below is used to convert from ASCII digits to a
  59.  * numerical equivalent.  It maps from '0' through 'z' to integers
  60.  * (100 for non-digit characters).
  61.  */
  62.  
  63. static char cvtIn[] = {
  64.     0, 1, 2, 3, 4, 5, 6, 7, 8, 9,        /* '0' - '9' */
  65.     100, 100, 100, 100, 100, 100, 100,        /* punctuation */
  66.     10, 11, 12, 13, 14, 15, 16, 17, 18, 19,    /* 'A' - 'Z' */
  67.     20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  68.     30, 31, 32, 33, 34, 35,
  69.     100, 100, 100, 100, 100, 100,        /* punctuation */
  70.     10, 11, 12, 13, 14, 15, 16, 17, 18, 19,    /* 'a' - 'z' */
  71.     20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  72.     30, 31, 32, 33, 34, 35};
  73.  
  74. /*
  75.  *----------------------------------------------------------------------
  76.  *
  77.  * strtoul --
  78.  *
  79.  *    Convert an ASCII string into an integer.
  80.  *
  81.  * Results:
  82.  *    The return value is the integer equivalent of string.  If endPtr
  83.  *    is non-NULL, then *endPtr is filled in with the character
  84.  *    after the last one that was part of the integer.  If string
  85.  *    doesn't contain a valid integer value, then zero is returned
  86.  *    and *endPtr is set to string.
  87.  *
  88.  * Side effects:
  89.  *    None.
  90.  *
  91.  *----------------------------------------------------------------------
  92.  */
  93.  
  94. unsigned long int
  95. strtoul(string, endPtr, base)
  96.     char *string;        /* String of ASCII digits, possibly
  97.                  * preceded by white space.  For bases
  98.                  * greater than 10, either lower- or
  99.                  * upper-case digits may be used.
  100.                  */
  101.     char **endPtr;        /* Where to store address of terminating
  102.                  * character, or NULL. */
  103.     int base;            /* Base for conversion.  Must be less
  104.                  * than 37.  If 0, then the base is chosen
  105.                  * from the leading characters of string:
  106.                  * "0x" means hex, "0" means octal, anything
  107.                  * else means decimal.
  108.                  */
  109. {
  110.     register char *p;
  111.     register unsigned long int result = 0;
  112.     register unsigned digit;
  113.     int anyDigits = FALSE;
  114.  
  115.     /*
  116.      * Skip any leading blanks.
  117.      */
  118.  
  119.     p = string;
  120.     while (isspace(*p)) {
  121.     p += 1;
  122.     }
  123.  
  124.     /*
  125.      * If no base was provided, pick one from the leading characters
  126.      * of the string.
  127.      */
  128.     
  129.     if (base == 0)
  130.     {
  131.     if (*p == '0') {
  132.         p += 1;
  133.         if (*p == 'x') {
  134.         p += 1;
  135.         base = 16;
  136.         } else {
  137.  
  138.         /*
  139.          * Must set anyDigits here, otherwise "0" produces a
  140.          * "no digits" error.
  141.          */
  142.  
  143.         anyDigits = TRUE;
  144.         base = 8;
  145.         }
  146.     }
  147.     else base = 10;
  148.     } else if (base == 16) {
  149.  
  150.     /*
  151.      * Skip a leading "0x" from hex numbers.
  152.      */
  153.  
  154.     if ((p[0] == '0') && (p[1] == 'x')) {
  155.         p += 2;
  156.     }
  157.     }
  158.  
  159.     /*
  160.      * Sorry this code is so messy, but speed seems important.  Do
  161.      * different things for base 8, 10, 16, and other.
  162.      */
  163.  
  164.     if (base == 8) {
  165.     for ( ; ; p += 1) {
  166.         digit = *p - '0';
  167.         if (digit > 7) {
  168.         break;
  169.         }
  170.         result = (result << 3) + digit;
  171.         anyDigits = TRUE;
  172.     }
  173.     } else if (base == 10) {
  174.     for ( ; ; p += 1) {
  175.         digit = *p - '0';
  176.         if (digit > 9) {
  177.         break;
  178.         }
  179.         result = (10*result) + digit;
  180.         anyDigits = TRUE;
  181.     }
  182.     } else if (base == 16) {
  183.     for ( ; ; p += 1) {
  184.         digit = *p - '0';
  185.         if (digit > ('z' - '0')) {
  186.         break;
  187.         }
  188.         digit = cvtIn[digit];
  189.         if (digit > 15) {
  190.         break;
  191.         }
  192.         result = (result << 4) + digit;
  193.         anyDigits = TRUE;
  194.     }
  195.     } else {
  196.     for ( ; ; p += 1) {
  197.         digit = *p - '0';
  198.         if (digit > ('z' - '0')) {
  199.         break;
  200.         }
  201.         digit = cvtIn[digit];
  202.         if (digit >= base) {
  203.         break;
  204.         }
  205.         result = result*base + digit;
  206.         anyDigits = TRUE;
  207.     }
  208.     }
  209.  
  210.     /*
  211.      * See if there were any digits at all.
  212.      */
  213.  
  214.     if (!anyDigits) {
  215.     p = string;
  216.     }
  217.  
  218.     if (endPtr != NULL) {
  219.     *endPtr = p;
  220.     }
  221.  
  222.     return result;
  223. }
  224. @
  225.  
  226.  
  227. 1.2.1.1
  228. log
  229. @Initial branch for Sprite server.
  230. @
  231. text
  232. @d17 1
  233. a17 1
  234. static char rcsid[] = "$Header: /sprite/src/lib/c/stdlib/RCS/strtoul.c,v 1.2 89/03/22 00:47:33 rab Exp $ SPRITE (Berkeley)";
  235. @
  236.  
  237.  
  238. 1.1
  239. log
  240. @Initial revision
  241. @
  242. text
  243. @d17 2
  244. a18 2
  245. static char rcsid[] = "$Header: strtol.c,v 1.1 88/04/28 17:20:29 ouster Exp $ SPRITE (Berkeley)";
  246. #endif not lint
  247. d20 2
  248. a22 8
  249.  
  250. #ifndef TRUE
  251. #define TRUE 1
  252. #define FALSE 0
  253. #endif
  254. #ifndef NULL
  255. #define NULL 0
  256. #endif
  257. @
  258.